package com.cykj.shop.service.impl;

import com.cykj.shop.domain.BsDeliveryFeeRule;
import com.cykj.shop.domain.dto.DeliveryFeeRuleDto;
import com.cykj.shop.mapper.DeliveryFeeRuleMapper;
import com.cykj.shop.service.IDeliveryFeeRuleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * 配送费规则Service业务层处理
 * 
 * @author cykj
 * @date 2025-01-20
 */
@Service
public class DeliveryFeeRuleServiceImpl implements IDeliveryFeeRuleService {
    
    @Autowired
    private DeliveryFeeRuleMapper deliveryFeeRuleMapper;
    
    /**
     * 查询配送费规则列表
     * 
     * @param rule 配送费规则查询条件
     * @return 配送费规则集合
     */
    @Override
    public List<BsDeliveryFeeRule> selectDeliveryFeeRuleList(BsDeliveryFeeRule rule) {
        return deliveryFeeRuleMapper.selectDeliveryFeeRuleList(rule);
    }
    
    /**
     * 根据ID查询配送费规则
     * 
     * @param id 配送费规则ID
     * @return 配送费规则
     */
    @Override
    public BsDeliveryFeeRule selectDeliveryFeeRuleById(Long id) {
        return deliveryFeeRuleMapper.selectDeliveryFeeRuleById(id);
    }
    
    /**
     * 根据商家ID查询配送费规则列表
     * 
     * @param shopId 商家ID
     * @return 配送费规则集合
     */
    @Override
    public List<BsDeliveryFeeRule> selectDeliveryFeeRuleByShopId(Long shopId) {
        return deliveryFeeRuleMapper.selectDeliveryFeeRuleByShopId(shopId);
    }
    
    /**
     * 根据商家ID查询启用的配送费规则
     * 
     * @param shopId 商家ID
     * @return 配送费规则
     */
    @Override
    public BsDeliveryFeeRule selectActiveDeliveryFeeRuleByShopId(Long shopId) {
        return deliveryFeeRuleMapper.selectActiveDeliveryFeeRuleByShopId(shopId);
    }
    
    /**
     * 新增配送费规则
     * 
     * @param ruleDto 配送费规则
     * @return 结果
     */
    @Override
    @Transactional
    public int insertDeliveryFeeRule(DeliveryFeeRuleDto ruleDto) {
        // 检查规则名称是否已存在
        if (checkRuleNameExists(ruleDto.getRuleId(), ruleDto.getShopId(), null)) {
            throw new RuntimeException("规则名称已存在");
        }
        
        BsDeliveryFeeRule rule = new BsDeliveryFeeRule();
        BeanUtils.copyProperties(ruleDto, rule);
        rule.setCreateTime(new Date());
        
        // 默认设置为启用状态
        if (rule.getIsActive() == null) {
            rule.setIsActive(1);
        }
        
        // 如果新规则是启用状态，需要禁用该商家的其他规则
        if (rule.getIsActive() == 1) {
            deliveryFeeRuleMapper.disableAllRulesByShopId(rule.getShopId());
        }
        
        return deliveryFeeRuleMapper.insertDeliveryFeeRule(rule);
    }
    
    /**
     * 修改配送费规则
     * 
     * @param ruleDto 配送费规则
     * @return 结果
     */
    @Override
    @Transactional
    public int updateDeliveryFeeRule(DeliveryFeeRuleDto ruleDto) {
        // 检查规则名称是否已存在（排除当前规则）
        if (checkRuleNameExists(ruleDto.getRuleId(), ruleDto.getShopId(), ruleDto.getId())) {
            throw new RuntimeException("规则名称已存在");
        }
        
        BsDeliveryFeeRule rule = new BsDeliveryFeeRule();
        BeanUtils.copyProperties(ruleDto, rule);
        
        // 如果修改后的规则是启用状态，需要禁用该商家的其他规则
        if (rule.getIsActive() != null && rule.getIsActive() == 1) {
            deliveryFeeRuleMapper.disableAllRulesByShopId(rule.getShopId());
        }
        
        return deliveryFeeRuleMapper.updateDeliveryFeeRule(rule);
    }
    
    /**
     * 删除配送费规则
     * 
     * @param id 配送费规则ID
     * @return 结果
     */
    @Override
    public int deleteDeliveryFeeRuleById(Long id) {
        return deliveryFeeRuleMapper.deleteDeliveryFeeRuleById(id);
    }
    
    /**
     * 批量删除配送费规则
     * 
     * @param ids 需要删除的配送费规则ID
     * @return 结果
     */
    @Override
    public int deleteDeliveryFeeRuleByIds(Long[] ids) {
        return deliveryFeeRuleMapper.deleteDeliveryFeeRuleByIds(ids);
    }
    
    /**
     * 启用配送费规则（会禁用该商家的其他规则）
     * 
     * @param id 配送费规则ID
     * @return 结果
     */
    @Override
    @Transactional
    public int enableDeliveryFeeRule(Long id) {
        BsDeliveryFeeRule rule = deliveryFeeRuleMapper.selectDeliveryFeeRuleById(id);
        if (rule == null) {
            throw new RuntimeException("配送费规则不存在");
        }
        
        // 先禁用该商家的所有规则
        deliveryFeeRuleMapper.disableAllRulesByShopId(rule.getShopId());
        
        // 再启用指定规则
        rule.setIsActive(1);
        return deliveryFeeRuleMapper.updateDeliveryFeeRule(rule);
    }
    
    /**
     * 禁用配送费规则
     * 
     * @param id 配送费规则ID
     * @return 结果
     */
    @Override
    public int disableDeliveryFeeRule(Long id) {
        BsDeliveryFeeRule rule = new BsDeliveryFeeRule();
        rule.setId(id);
        rule.setIsActive(0);
        return deliveryFeeRuleMapper.updateDeliveryFeeRule(rule);
    }
    
    /**
     * 计算配送费
     * 
     * @param shopId 商家ID
     * @param distance 配送距离(公里)
     * @return 配送费
     */
    @Override
    public BigDecimal calculateDeliveryFee(Long shopId, BigDecimal distance) {
        // 获取商家的启用配送费规则
        BsDeliveryFeeRule rule = deliveryFeeRuleMapper.selectActiveDeliveryFeeRuleByShopId(shopId);
        if (rule == null) {
            throw new RuntimeException("该商家未设置配送费规则");
        }
        
        // 检查是否超出最大配送距离
        if (rule.getMaxDistance() != null && distance.compareTo(rule.getMaxDistance()) > 0) {
            throw new RuntimeException("超出最大配送距离");
        }
        
        BigDecimal deliveryFee = rule.getBaseFee();
        
        // 如果距离超出基础距离，计算额外费用
        if (distance.compareTo(rule.getBaseDistance()) > 0) {
            BigDecimal extraDistance = distance.subtract(rule.getBaseDistance());
            // 计算需要多少个计费单位（向上取整）
            BigDecimal units = extraDistance.divide(rule.getExtraUnitDistance(), RoundingMode.UP);
            // 计算额外费用
            BigDecimal extraFee = units.multiply(rule.getExtraUnitFee());
            deliveryFee = deliveryFee.add(extraFee);
        }
        
        return deliveryFee.setScale(2, RoundingMode.HALF_UP);
    }
    
    /**
     * 检查规则名称是否已存在
     * 
     * @param ruleId 规则名称
     * @param shopId 商家ID
     * @param excludeId 排除的规则ID（用于更新时检查）
     * @return 是否存在
     */
    @Override
    public boolean checkRuleNameExists(String ruleId, Long shopId, Long excludeId) {
        int count = deliveryFeeRuleMapper.checkRuleNameExists(ruleId, shopId, excludeId);
        return count > 0;
    }
}
